using System;
using System.CodeDom;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace CodeDom
{
  internal class ListFieldPropertyGenerator : TemplateFieldGenerator
  {
    public ListFieldPropertyGenerator(TemplateField field)
      : base(field)
    {
    }

    #region Overrides of FieldPropertyGenerator

    public override void AddValueConversionStatements(CodeExpression itemReference, CodeMemberMethod method)
    {
      method.Statements.Add(CreateFieldValueVariableStatement(itemReference));     
      method.Statements.Add(CreateSplitStringVariable());
      method.Statements.Add(CreateIDConversionAndReturnStatement());
    }

    public override CodeTypeReference GetFieldType()
    {
      return new CodeTypeReference("IEnumerable<ID>");
    }

    private CodeMethodReturnStatement CreateIDConversionAndReturnStatement()
    {
      //HACK: Code dom does not support lambdas (this makes the code c# only)
      CodeExpression parseLambda = new CodeSnippetExpression("s => ID.Parse(s, ID.Null)");
      var linqConversion = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("values"), "Select", parseLambda);
      CodeExpression limitLambda = new CodeSnippetExpression("id => !id.IsNull");
      linqConversion = new CodeMethodInvokeExpression(linqConversion, "Where", limitLambda);
      var returnStatement = new CodeMethodReturnStatement(linqConversion);
      return returnStatement;
    }

    private CodeVariableDeclarationStatement CreateSplitStringVariable()
    {
      var fieldValueReference = new CodeVariableReferenceExpression("fieldValue");
      var splitStatement = new CodeMethodInvokeExpression(fieldValueReference, "Split", new CodeMethodInvokeExpression(new CodePrimitiveExpression("|"), "ToCharArray"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("StringSplitOptions"), "RemoveEmptyEntries"));
      var stringsVariable = new CodeVariableDeclarationStatement("String[]", "values", splitStatement);
      return stringsVariable;
    }

    #endregion
  }
}